#include "scheduler/reactive_sequence_scheduler.h"
#include "../policy/policy_factory.h"
#include "../policy/behavior_tree/behavior_tree_reactive_sequence_policy.h"

namespace scheduler
{
ReactiveSequenceScheduler::ReactiveSequenceScheduler(const std::string &name)
    : AbstractScheduler(name)
{
    schedule_policy_ = policy::PolicyFactory<policy::BehaviorTreeReactiveSequencePolicy>::createPolicy(name);
}
bool ReactiveSequenceScheduler::setReactiveTask(const task::AbstractTaskConstPtr &task)
{
    if (task->getTaskType() == task::TaskType::SYNC_TASK)
    {
        EASE_ERROR("reactive sequence scheduler appended reactive task cannot be sync task, must request task");
        throw std::runtime_error("reactive sequence scheduler appended reactive task cannot be sync task, must request task");
    }
    else if (task->getTaskType() == task::TaskType::SYNC_REQUEST_TASK)
    {
        auto policy = dynamic_cast<policy::BehaviorTreeReactiveSequencePolicy *>(schedule_policy_.get());
        if (nullptr == policy)
        {
            throw std::runtime_error("reactive sequence scheduler policy case fail");
        }
        return policy->setReactiveTask(task);
    }
    else
    {
        EASE_ERROR("reactive sequence scheduler appended reactive task error");
        throw std::runtime_error("reactive sequence scheduler appended reactive task error");
    }
}
bool ReactiveSequenceScheduler::setReactiveScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    auto policy = dynamic_cast<policy::BehaviorTreeReactiveSequencePolicy *>(schedule_policy_.get());
    if (nullptr == policy)
    {
        throw std::runtime_error("reactive sequence scheduler policy case fail");
    }
    scheduler_vec_.push_back(scheduler);
    return policy->setReactivePolicy(scheduler->getTaskPolicy());
}
bool ReactiveSequenceScheduler::appendExecuteTask(const task::AbstractTaskConstPtr &task)
{
    return AbstractScheduler::appendTask(task);
}
bool ReactiveSequenceScheduler::appendExecuteScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    return AbstractScheduler::appendScheduler(scheduler);
}

bool ReactiveSequenceScheduler::appendTask(const task::AbstractTaskConstPtr &task)
{
    EASE_ERROR("reactive sequence cannot append task");
    throw std::runtime_error("reactive sequence scheduler cannot append task");
}
bool ReactiveSequenceScheduler::appendScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    EASE_ERROR("reactive sequence cannot append scheduler");
    throw std::runtime_error("reactive sequence scheduler cannot append scheduler");
}
bool ReactiveSequenceScheduler::setTask(const task::AbstractTaskConstPtr &task)
{
    EASE_ERROR("reactive sequence cannot set task");
    throw std::runtime_error("reactive sequence scheduler cannot set task");
}
bool ReactiveSequenceScheduler::setScheduler(const AbstractSchedulerConstPtr &scheduler)
{
    EASE_ERROR("reactive sequence cannot set scheduler");
    throw std::runtime_error("reactive sequence scheduler cannot set scheduler");
}
scheduler::ReactiveSequenceScheduler::~ReactiveSequenceScheduler() = default;
}
